package com.itheima.filter;

import com.itheima.utils.CurrentHolder;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;

import java.io.IOException;

/**
 * 登录校验,解析token
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {
    //每次请求都经过的方法
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        //1. 登录请求放行
        // 获取请求路径
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        String path = req.getRequestURI();
        log.info("请求路径：{}", path);
        // 判断是否是登录请求, 只有以/login结尾才放行
        if(path.endsWith("/login")){
            chain.doFilter(servletRequest, servletResponse);
            return;
        }
        //2. 其它请求要校验token的有效性
        //2.1 获取请求头中的token
        String token = req.getHeader("Token");
        log.info("请求头中的token：{}", token);
        if(StringUtils.hasText( token)) {
            // token有值
            //3. 有效就放行，无效就拒绝
            //3.1 校验
            try {
                Claims claims = JwtUtils.parseJWT(token);
                log.info("token内容：{}", claims);
                //获取登录用户id
                //Integer employeeId = (Integer) claims.get("id");
                Integer userId = claims.get("id", Integer.class);
                //存入threadlocal
                CurrentHolder.setCurrentId(userId);
                //3.2 不报错说明校验通过,通过就要放行
                chain.doFilter(servletRequest, servletResponse);
                //放行后执行
                log.info("TokenFitler  controller执行后....");
                return;
            } catch (Exception e) {
                log.error("解析token失败", e);
            } finally {
                //使用后要移除，防止内存泄漏
                CurrentHolder.remove();
            }
        }
        // 没有token或失败的处理
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        // 设置状态码为401，用户没有登录
        res.setStatus(HttpStatus.UNAUTHORIZED.value());
    }
}
